<!-- 设备物模型 -> 运行状态 -> 查看数据（设备的属性值历史）-->
<template>
  <Modal
    v-model:open="dialogVisible"
    title="查看数据"
    width="1200px"
    :destroy-on-close="true"
    @cancel="handleClose"
  >
    <div class="property-history-container">
      <!-- 工具栏 -->
      <div class="toolbar-wrapper mb-4">
        <a-space :size="12" class="w-full" wrap>
          <!-- 时间选择 -->
          <a-range-picker
            v-model:value="dateRange"
            :show-time="{ format: 'HH:mm:ss' }"
            format="YYYY-MM-DD HH:mm:ss"
            :placeholder="['开始时间', '结束时间']"
            class="!w-[400px]"
            @change="handleTimeChange"
          />

          <!-- 刷新按钮 -->
          <a-button @click="handleRefresh" :loading="loading">
            <template #icon>
              <Icon icon="ant-design:reload-outlined" />
            </template>
            刷新
          </a-button>

          <!-- 导出按钮 -->
          <a-button @click="handleExport" :loading="exporting" :disabled="list.length === 0">
            <template #icon>
              <Icon icon="ant-design:export-outlined" />
            </template>
            导出
          </a-button>

          <!-- 视图切换 -->
          <a-button-group class="ml-auto">
            <a-button
              :type="viewMode === 'chart' ? 'primary' : 'default'"
              @click="viewMode = 'chart'"
              :disabled="isComplexDataType"
            >
              <template #icon>
                <Icon icon="ant-design:line-chart-outlined" />
              </template>
              图表
            </a-button>
            <a-button :type="viewMode === 'list' ? 'primary' : 'default'" @click="viewMode = 'list'">
              <template #icon>
                <Icon icon="ant-design:table-outlined" />
              </template>
              列表
            </a-button>
          </a-button-group>
        </a-space>

        <!-- 数据统计信息 -->
        <div v-if="list.length > 0" class="mt-3 text-sm text-gray-600">
          <a-space :size="16">
            <span>共 {{ total }} 条数据</span>
            <span v-if="viewMode === 'chart' && !isComplexDataType">
              最大值: {{ maxValue }} | 最小值: {{ minValue }} | 平均值: {{ avgValue }}
            </span>
          </a-space>
        </div>
      </div>

      <!-- 数据展示区域 -->
      <a-spin :spinning="loading" :delay="200">
        <!-- 图表模式 -->
        <div v-if="viewMode === 'chart'" class="chart-container">
          <a-empty
            v-if="list.length === 0"
            :image="Empty.PRESENTED_IMAGE_SIMPLE"
            description="暂无数据"
            class="py-20"
          />
          <EchartsUI v-else ref="chartRef" height="500px" />
        </div>

        <!-- 表格模式 -->
        <div v-else class="table-container">
          <a-table
            :dataSource="list"
            :columns="tableColumns"
            :pagination="paginationConfig"
            :scroll="{ y: 500 }"
            row-key="updateTime"
            size="small"
          >
            <template #bodyCell="{ column, record }">
              <template v-if="column.key === 'updateTime'">
                {{ formatDate(new Date(record.updateTime)) }}
              </template>
              <template v-else-if="column.key === 'value'">
                <a-tag v-if="isComplexDataType" color="processing">
                  {{ formatComplexValue(record.value) }}
                </a-tag>
                <span v-else class="font-medium">{{ record.value }}</span>
              </template>
            </template>
          </a-table>
        </div>
      </a-spin>
    </div>

    <template #footer>
      <a-button @click="handleClose">关闭</a-button>
    </template>
  </Modal>
</template>
<script setup lang="ts">
import type { EchartsUIType } from '@vben/plugins/echarts'
import type { IotDevicePropertyRespVO } from '#/api/iot/device/device'

import { computed, nextTick, reactive, ref, watch } from 'vue'

import { EchartsUI, useEcharts } from '@vben/plugins/echarts'
import { beginOfDay, endOfDay, formatDate } from '@vben/utils'

import { Empty, message, Modal } from 'ant-design-vue'
import dayjs, { type Dayjs } from 'dayjs'

import { DeviceApi } from '#/api/iot/device/device'
import { IoTDataSpecsDataTypeEnum } from '#/views/iot/utils/constants'

defineProps<{ deviceId: number }>()

/** IoT 设备属性历史数据详情 */
defineOptions({ name: 'DeviceDetailsThingModelPropertyHistory' })

const dialogVisible = ref(false) // 弹窗的是否展示
const loading = ref(false)
const exporting = ref(false)
const viewMode = ref<'chart' | 'list'>('chart') // 视图模式状态
const list = ref<IotDevicePropertyRespVO[]>([]) // 列表的数据
const total = ref(0) // 总数据量
const thingModelDataType = ref<string>('') // 物模型数据类型
const propertyIdentifier = ref<string>('') // 属性标识符
const dateRange = ref<[Dayjs, Dayjs]>([
  dayjs().subtract(7, 'day').startOf('day'),
  dayjs().endOf('day')
])

const queryParams = reactive({
  deviceId: -1,
  identifier: '',
  times: [
    formatDate(beginOfDay(new Date(new Date().getTime() - 3600 * 1000 * 24 * 7))),
    formatDate(endOfDay(new Date()))
  ]
})

// Echarts 相关
const chartRef = ref<EchartsUIType>()
const { renderEcharts } = useEcharts(chartRef)

// 判断是否为复杂数据类型（struct 或 array）
const isComplexDataType = computed(() => {
  if (!thingModelDataType.value) return false
  return [IoTDataSpecsDataTypeEnum.STRUCT, IoTDataSpecsDataTypeEnum.ARRAY].includes(
    thingModelDataType.value as any
  )
})

// 统计数据
const maxValue = computed(() => {
  if (isComplexDataType.value || list.value.length === 0) return '-'
  const values = list.value.map((item) => Number(item.value)).filter((v) => !isNaN(v))
  return values.length > 0 ? Math.max(...values).toFixed(2) : '-'
})

const minValue = computed(() => {
  if (isComplexDataType.value || list.value.length === 0) return '-'
  const values = list.value.map((item) => Number(item.value)).filter((v) => !isNaN(v))
  return values.length > 0 ? Math.min(...values).toFixed(2) : '-'
})

const avgValue = computed(() => {
  if (isComplexDataType.value || list.value.length === 0) return '-'
  const values = list.value.map((item) => Number(item.value)).filter((v) => !isNaN(v))
  if (values.length === 0) return '-'
  const sum = values.reduce((acc, val) => acc + val, 0)
  return (sum / values.length).toFixed(2)
})

// 表格列配置
const tableColumns = computed(() => [
  {
    title: '序号',
    key: 'index',
    width: 80,
    align: 'center',
    customRender: ({ index }: { index: number }) => index + 1
  },
  {
    title: '时间',
    key: 'updateTime',
    dataIndex: 'updateTime',
    width: 200,
    align: 'center'
  },
  {
    title: '属性值',
    key: 'value',
    dataIndex: 'value',
    align: 'center'
  }
])

// 分页配置
const paginationConfig = computed(() => ({
  current: 1,
  pageSize: 20,
  total: total.value,
  showSizeChanger: true,
  showQuickJumper: true,
  pageSizeOptions: ['10', '20', '50', '100'],
  showTotal: (total: number) => `共 ${total} 条数据`
}))

/** 获得设备历史数据 */
const getList = async () => {
  loading.value = true
  try {
    const data = await DeviceApi.getHistoryDevicePropertyList(queryParams)
    list.value = data?.list || []
    total.value = list.value.length
    
    // 如果是图表模式且不是复杂数据类型，渲染图表
    if (viewMode.value === 'chart' && !isComplexDataType.value && list.value.length > 0) {
      await nextTick()
      renderChart()
    }
  } catch (error) {
    message.error('获取数据失败')
    list.value = []
    total.value = 0
  } finally {
    loading.value = false
  }
}

/** 渲染图表 */
const renderChart = () => {
  if (!list.value || list.value.length === 0) return

  const chartData = list.value.map((item) => [item.updateTime, item.value])

  renderEcharts({
    title: {
      text: '属性值趋势',
      left: 'center',
      textStyle: {
        fontSize: 16,
        fontWeight: 'normal'
      }
    },
    grid: {
      left: 60,
      right: 60,
      bottom: 100,
      top: 80,
      containLabel: true
    },
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'cross'
      },
      formatter: (params: any) => {
        const param = params[0]
        return `
          <div style="padding: 8px;">
            <div style="margin-bottom: 4px; font-weight: bold;">
              ${formatDate(new Date(param.value[0]), 'YYYY-MM-DD HH:mm:ss')}
            </div>
            <div>
              <span style="display:inline-block;margin-right:5px;border-radius:50%;width:10px;height:10px;background-color:${param.color};"></span>
              <span>属性值: <strong>${param.value[1]}</strong></span>
            </div>
          </div>
        `
      }
    },
    xAxis: {
      type: 'time',
      name: '时间',
      nameTextStyle: {
        padding: [10, 0, 0, 0]
      },
      axisLabel: {
        formatter: (value: number) => {
          return String(formatDate(new Date(value), 'MM-DD HH:mm') || '')
        }
      }
    },
    yAxis: {
      type: 'value',
      name: '属性值',
      nameTextStyle: {
        padding: [0, 0, 10, 0]
      }
    },
    series: [
      {
        name: '属性值',
        type: 'line',
        smooth: true,
        symbol: 'circle',
        symbolSize: 6,
        lineStyle: {
          width: 2,
          color: '#1890FF'
        },
        itemStyle: {
          color: '#1890FF'
        },
        areaStyle: {
          color: {
            type: 'linear',
            x: 0,
            y: 0,
            x2: 0,
            y2: 1,
            colorStops: [
              {
                offset: 0,
                color: 'rgba(24, 144, 255, 0.3)'
              },
              {
                offset: 1,
                color: 'rgba(24, 144, 255, 0.05)'
              }
            ]
          }
        },
        data: chartData
      }
    ],
    dataZoom: [
      {
        type: 'inside',
        start: 0,
        end: 100
      },
      {
        type: 'slider',
        height: 30,
        bottom: 20
      }
    ]
  })
}

/** 打开弹窗 */
const open = async (deviceId: number, identifier: string, dataType: string) => {
  dialogVisible.value = true
  queryParams.deviceId = deviceId
  queryParams.identifier = identifier
  propertyIdentifier.value = identifier
  thingModelDataType.value = dataType

  // 如果物模型是 struct、array，需要默认使用 list 模式
  if (isComplexDataType.value) {
    viewMode.value = 'list'
  } else {
    viewMode.value = 'chart'
  }

  // 等待弹窗完全渲染后再获取数据
  await nextTick()
  await getList()
}

/** 时间变化处理 */
const handleTimeChange = () => {
  if (!dateRange.value || dateRange.value.length !== 2) {
    return
  }

  queryParams.times = [
    formatDate(dateRange.value[0].toDate()),
    formatDate(dateRange.value[1].toDate())
  ]
  
  getList()
}

/** 刷新数据 */
const handleRefresh = () => {
  getList()
}

/** 导出数据 */
const handleExport = async () => {
  if (list.value.length === 0) {
    message.warning('暂无数据可导出')
    return
  }

  exporting.value = true
  try {
    // 构建CSV内容
    const headers = ['序号', '时间', '属性值']
    const csvContent = [
      headers.join(','),
      ...list.value.map((item, index) => {
        return [
          index + 1,
          formatDate(new Date(item.updateTime)),
          isComplexDataType.value ? `"${JSON.stringify(item.value)}"` : item.value
        ].join(',')
      })
    ].join('\n')

    // 创建 BOM 头,解决中文乱码
    const BOM = '\uFEFF'
    const blob = new Blob([BOM + csvContent], { type: 'text/csv;charset=utf-8' })
    
    // 下载文件
    const url = window.URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = url
    link.download = `设备属性历史_${propertyIdentifier.value}_${formatDate(new Date(), 'YYYYMMDDHHmmss')}.csv`
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    window.URL.revokeObjectURL(url)

    message.success('导出成功')
  } catch (error) {
    message.error('导出失败')
  } finally {
    exporting.value = false
  }
}

/** 关闭弹窗 */
const handleClose = () => {
  dialogVisible.value = false
  list.value = []
  total.value = 0
}

/** 格式化复杂数据类型 */
const formatComplexValue = (value: any) => {
  if (typeof value === 'object') {
    return JSON.stringify(value)
  }
  return String(value)
}

/** 监听视图模式变化，重新渲染图表 */
watch(viewMode, async (newMode) => {
  if (newMode === 'chart' && !isComplexDataType.value && list.value.length > 0) {
    await nextTick()
    renderChart()
  }
})

defineExpose({ open }) // 提供 open 方法，用于打开弹窗
</script>

<style scoped lang="scss">
.property-history-container {
  max-height: 70vh;
  overflow: auto;

  .toolbar-wrapper {
    padding: 16px;
    background-color: #fafafa;
    border-radius: 8px;
  }

  .chart-container,
  .table-container {
    padding: 16px;
    background-color: #fff;
    border-radius: 8px;
  }
}
</style>

